package org.dlsu.mt.parser.generation;
import java.util.StringTokenizer;
import java.util.Vector;

public class Grammar
{
	String left;
	Vector<String> right;
	int counter = 0;
	
	public Grammar(String right, String left)
	{
		this.left = left;
		parseRight(right);
	}
	
	public void parseRight(String right)
	{
		this.right = new Vector();
		StringTokenizer tk = new StringTokenizer(right, " ");
		while(tk.hasMoreTokens())
		{
			String temp = tk.nextToken();
			this.right.addElement(temp);
		}
	}
	
	public String getLeft()
	{
		return left;
	}
	
	public String getSymbols()
	{
		StringBuffer temp = new StringBuffer();
		for(int i=0;i<right.size();i++)
		{
			if(i == 0)
			{
				temp.append(right.get(i));
			}
			else
			{
				temp.append(" " + right.get(i));
			}
		}
		return temp.toString();
	}
	
	public String getNextSymbol()
	{
		if(counter<right.size())
		{
			counter++;
			return right.get(counter-1);
		}
		else
			return null;
	}
	
	public boolean hasMoreSymbols()
	{
		if(counter<right.size())
			return true;
		else
			return false;
	}
	
	public int getNumSymbols()
	{
		return right.size();
	}
	
	public boolean isFound(String symbol)
	{
		for(int i = 0;i<right.size();i++)
		{
			if(right.get(i).equals(symbol))
				return true;
		}
		return false;
	}
	
	public int findPos(String symbol)
	{
		for(int i = right.size()-1;i>-1;i--)
		{
			if(right.get(i).equals(symbol))
				return i;
		}
		return -1;
	}
	
	public void resetCounter()
	{
		counter = 0;
	}
	
	public String getSymbol(int index)
	{
		return right.get(index);
	}
	
	/**compares which symbol comes first in the rule
	 * returns 1 if sym1 comes first
	 * returns 2 if sym2 comes first
	 * returns 3 if sym1 and sym2 are equal (same symbol)
	 * returns 0 if either one is not found in the rule
	 */
	public int compare(String sym1, String sym2)
	{
		int pos1 = findPos(sym1);
		int pos2 = findPos(sym2);
		
		if(pos1!=-1&&pos2!=-1)
		{
			if(pos1>pos2)
				return 2;
			else if(pos1<pos2)
				return 1;
			else
				return 3;
		}
		else
		{
			return 0;
		}
	}
	
	public Vector<String> getAnnotations()
	{
		Vector<String> tempList = new Vector();
		boolean found = false;
		for(int i = 0; i<right.size();i++)
		{
			if(found)
			{
				if(right.get(i).equals("="))
				{
					if(Character.isLowerCase(right.get(i-2).charAt(0)))
						tempList.add(right.get(i-2));
					else
						tempList.add("!"+right.get(i-2));
				}
				else
				{
					tempList.add(right.get(i));
				}
				found = false;
			}
			if(right.get(i).equals("*[/"))
			{
				found = true;
			}
		}
		return tempList;
	}
	
	public Vector<String> getTerminals()
	{
		Vector<String> tempList = new Vector();
		for(int i=0; i<right.size();i++)
		{
			if(Character.isLowerCase(right.get(i).charAt(0)))
				tempList.add(right.get(i));
		}
		return tempList;
	}
	
	public float getRatioFound(Vector<String> symbols)
	{
		float count = 0;
		for(int i=0;i<symbols.size();i++)
		{
			if(isFound(symbols.get(i)))
				count+=1;
		}
		count = count/symbols.size();
		if(getAnnotations().size() > symbols.size())
		{
			for(int i=0;i<getAnnotations().size()-symbols.size();i++)
				count -= .001;
		}
		Vector<String> tempList = getTerminals();
		for(int i=0;i<tempList.size();i++)
		{
			boolean found = false;
			for(int x=0;x<symbols.size();x++)
				if(symbols.get(x).equals(tempList.get(i)))
					found = true;
			if(!found)
				count=0;
		}
		return count;
	}
}